package com.example.project.controller;

import java.util.*;

import com.example.project.entity.Comment;
import com.example.project.entity.User;
import com.example.project.mapper.CommentMapper;
import com.example.project.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.project.entity.Tourism;
import com.example.project.mapper.TourismMapper;

/**
 * 景点管理Controller
 *
 * @author changyao
 * @date 2024-11-11
 */
@RestController
@RequestMapping("/project/tourism")
public class TourismController {
    @Autowired
    private TourismMapper tourismMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CommentMapper commentMapper;

    /**
     * 查询景点管理列表
     */
    @GetMapping("/list")
    public List<Tourism> list() {
        QueryWrapper<Tourism> queryWrapper = new QueryWrapper<>();
        return tourismMapper.selectList(queryWrapper);
    }


    /**
     * 获取景点管理详细信息
     */
    @PostMapping("/detil")
    public Tourism getInfo(@RequestBody Tourism tourism) {
        return tourismMapper.selectById(tourism);
    }


    /**
     * 新增景点管理
     */
    @PostMapping("/add")
    public int add(@RequestBody Tourism tourism) {
        return tourismMapper.insert(tourism);
    }

    /**
     * 修改景点管理
     */
    @PostMapping("/edit")
    public int edit(@RequestBody Tourism tourism) {
        return tourismMapper.updateById(tourism);
    }

    /**
     * 删除景点管理
     */
    @PostMapping("/del")
    public int remove(@RequestBody Tourism tourism) {
        return tourismMapper.deleteById(tourism);
    }

    @GetMapping("/tourismCommended/{id}")
    public List<Tourism> travelSpot3(@PathVariable Long id) throws Exception {
        System.out.println("开始协同过滤热门景点");

        User user = userMapper.selectById(id);


        List<String> list = UserSim(String.valueOf(user.getId()));
        List<Tourism> list1 = new ArrayList<>();


        for (String tuijian : list) {
            System.out.println(tuijian);
            Tourism film = tourismMapper.selectById(tuijian);
//            RemenjingdianEntity remenjingdian =  remenjingdianService.findById(tuijian);
            list1.add(film);
        }


        return list1;

    }


    public List<String> UserSim(String u_id) throws Exception {
        List<String> newsList = new ArrayList<String>();
        String id = String.valueOf(u_id);
        Map<String, Map<String, Double>> userPerfMap = findList();
        Map<String, Map<String, Double>> UserObjMap = getAllObjUsers();

        //用于判断用户之间的关系系数
        System.out.println("userPerMap:---------------" + userPerfMap);
        //筛选出最终系数大于五
        System.out.println("UserObjMap:---------------" + UserObjMap);

        String output1 = "皮尔逊相关系数:";
        Map<String, Double> per = userPerfMap.get(u_id);
        Map<String, Double> simUserSimMap = new HashMap<String, Double>();
        for (Map.Entry<String, Map<String, Double>> userPerfEn : userPerfMap.entrySet()) {
            String userId = userPerfEn.getKey();
            if (!id.equals(userId) && userPerfEn.getValue() != null) {

                System.out.println("userPerfEnid:" + userPerfEn.getValue());
                double sim = getUserSimilar(per, userPerfEn.getValue());
                output1 += id + "与" + userId + "之间的相关系数:" + sim + ",";
                simUserSimMap.put(userId, sim);
            }
        }
        System.out.println(output1);
        System.out.println("根据系数推荐热门景点:");

        List<String> list = getRecommend(UserObjMap, simUserSimMap, id);
        System.out.println("axasxa" + list);


        Map<String, Double> liMap = UserObjMap.get(id);
        int flag = 1;
        for (int i = 0; i < list.size(); i++) {
            for (Map.Entry<String, Double> entry : liMap.entrySet()) {
                if (entry.getKey().equals(list.get(i))) {
                    flag = 0;
                    break;
                } else {
                    flag = 1;
                }
            }
            if (flag == 1) {
                newsList.add(list.get(i));
                //System.out.println();
            }
        }
        System.out.println(newsList);
        return newsList;//获得推荐景点
    }


    public Map<String, Map<String, Double>> findList() throws Exception {
        Map<String, Map<String, Double>> userPerfMap = new HashMap<String, Map<String, Double>>();

        List<User> users = userMapper.selectList(null);

        for (User u : users) {
            Map<String, Double> user = new HashMap<String, Double>();
            //对偏好进行处理
            //对景点评级进行处理
            String u_id = String.valueOf(u.getId());


            QueryWrapper<Comment> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", u_id);

            List<Comment> comments = commentMapper.selectList(wrapper);


            //对用户预算进行处理
            //对预算进行处理
            if (u.getUserBudget() == null || "null".equals(u.getUserBudget())) {
                user.put("xb", 0.0);
            } else {
                if (Double.valueOf(u.getUserBudget()) < 1000.0) {
                    user.put("xb", 1.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 1000.0 && Double.valueOf(u.getUserBudget()) < 2000.0) {
                    user.put("xb", 2.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 2000.0 && Double.valueOf(u.getUserBudget()) < 3000.0) {
                    user.put("xb", 3.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 3000.0 && Double.valueOf(u.getUserBudget()) < 4000.0) {
                    user.put("xb", 4.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 4000.0 && Double.valueOf(u.getUserBudget()) < 5000.0) {
                    user.put("xb", 5.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 5000.0 && Double.valueOf(u.getUserBudget()) < 6000.0) {
                    user.put("xb", 6.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 6000.0 && Double.valueOf(u.getUserBudget()) < 7000.0) {
                    user.put("xb", 7.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 7000.0 && Double.valueOf(u.getUserBudget()) < 8000.0) {
                    user.put("xb", 8.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 8000.0 && Double.valueOf(u.getUserBudget()) < 9000.0) {
                    user.put("xb", 9.0);
                } else if (Double.valueOf(u.getUserBudget()) >= 9000.0 && Double.valueOf(u.getUserBudget()) < 10000.0) {
                    user.put("xb", 10.0);
                } else {
                    user.put("xb", 11.0);
                }

            }

            if (u.getUserLike() == null || "null".equals(u.getUserLike())) {
                user.put("nl", 0.0);
            } else {
                user.put("nl", Double.valueOf(u.getUserLike()));
            }

            if (u.getUserTime() == null || "null".equals(u.getUserTime())) {
                user.put("nj", 0.0);
            } else {
                user.put("nj", Double.valueOf(u.getUserTime()));
            }


            //上面用户全部评级为5的影片信息，dr用于存放这些影片的信息
            List<Tourism> dr = new ArrayList<>();


            for (Comment comment : comments) {

                if (comment.getUserId() == comment.getUserId() && comment.getModule().equals("movie")) {
                    Tourism film = tourismMapper.selectById(comment.getFid());
                    dr.add(film);
                }

                if (comment.getType().equals("1")) {
                    user.put("cb", 1.0);
                }
                if (comment.getType().equals("2")) {
                    user.put("cb", 2.0);
                }
                if (comment.getType().equals("3")) {
                    user.put("cb", 3.0);
                }
                if (comment.getType().equals("4")) {
                    user.put("cb", 4.0);
                }
                if (comment.getType().equals("5")) {
                    user.put("cb", 5.0);
                }
            }


            for (int i = 0; i < dr.size(); i++) {
                Tourism dr1 = dr.get(i);
                String i1 = String.valueOf(i);
                String xxx = "0";

                if (dr1.getPrice().doubleValue() > 30) {
                    xxx = "1";
                } else if (dr1.getPrice().doubleValue() > 60) {
                    xxx = "2";
                }

                if (dr1.getPrice().doubleValue() > 90) {
                    xxx = "3";
                }

                if (dr1.getPrice().doubleValue() > 120) {
                    xxx = "4";
                }

                if (dr1.getPrice().doubleValue() > 150) {
                    xxx = "5";
                }


                Double score = Double.valueOf(xxx);
                user.put("tp" + i1, score);
            }
            for (Tourism film : dr) {
                System.out.println("film-----" + film);
            }


            System.out.println("-----" + user);

            String id = String.valueOf(u_id);
            userPerfMap.put(id, user);
        }
        return userPerfMap;
    }


    //
    public Map<String, Map<String, Double>> getAllObjUsers() throws Exception {
        Map<String, Map<String, Double>> simUserObjMap = new HashMap<String, Map<String, Double>>();
        //查询所有用户id


        List<User> users = userMapper.getUser();
        System.out.println("usersssssssssssssssssss::" + users);


        for (User u : users) {
            Map<String, Double> pobjMap = new HashMap<String, Double>();
            if (u != null) {
                String u_id = String.valueOf(u.getId());


                QueryWrapper<Comment> wrapper = new QueryWrapper<>();
                wrapper.eq("user_id", u_id);
                wrapper.orderByDesc("id");
                List<Comment> comments = commentMapper.selectList(wrapper);


                List<Tourism> records = new ArrayList<>();
                System.out.println("comments:----" + comments);
                for (Comment comment : comments) {


                    if (comment.getModule().equals("movie")) {
                        Tourism film = tourismMapper.selectById(comment.getFid());
                        records.add(film);
                    }
                    String xxx = "0";
                    if (comment.getType().equals("1")) {
                        xxx = "1";
                    }
                    if (comment.getType().equals("2")) {
                        xxx = "2";
                    }
                    if (comment.getType().equals("3")) {
                        xxx = "3";
                    }

                    if (comment.getType().equals("4")) {
                        xxx = "4";
                    }
                    if (comment.getType().equals("5")) {
                        xxx = "5";
                    }
                    String n_id = String.valueOf(comment.getFid());
                    double score = Double.valueOf(xxx);
                    pobjMap.put(n_id, score);

                }
                simUserObjMap.put(String.valueOf(u.getId()), pobjMap);

            } else {
                continue;
            }


        }
        return simUserObjMap;

    }


    //推荐景点
    private static List<String> getRecommend(Map<String, Map<String, Double>> simUserObjMap,
                                             Map<String, Double> simUserSimMap, String id) {
        Map<String, Double> objScoreMap = new HashMap<String, Double>();
        for (Map.Entry<String, Map<String, Double>> simUserEn : simUserObjMap.entrySet()) {
            String user = simUserEn.getKey();
            double sim = 0;
            if (!id.equals(user)) {
                sim = simUserSimMap.get(user);
//                System.out.println(user);
                for (Map.Entry<String, Double> simObjEn : simUserEn.getValue().entrySet()) {
                    double objScore = sim * simObjEn.getValue();
                    String objName = simObjEn.getKey();
//                    System.out.println(objName);
                    if (objScoreMap.get(objName) == null) {
                        objScoreMap.put(objName, objScore);
                    } else {
                        double totalScore = objScoreMap.get(objName);
                        objScoreMap.put(objName, totalScore + objScore);
                    }
                }
            }

        }
        List<Map.Entry<String, Double>> enList = new ArrayList<Map.Entry<String, Double>>(objScoreMap.entrySet());
        Collections.sort(enList, new Comparator<Map.Entry<String, Double>>() {
            public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
                Double a = o1.getValue() - o2.getValue();
                if (a == 0) {
                    return 0;
                } else if (a > 0) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
        List<String> list = new ArrayList<String>();
        for (int i = enList.size() - 1; i > -1; i--) {
            System.out.println(enList.get(i).getKey() + "--->" + enList.get(i).getValue());

        }


        for (int i = enList.size() - 1; i > -1; i--) {
            if (enList.get(i).getValue() > 2.5) {
                //筛选相性大于5的数据
//                System.out.printf("15315861614", enList.get(i).getKey());

                list.add(enList.get(i).getKey());
            }

        }
        System.out.println("筛选系数大于2.5的数据：" + list.size() + "个");
        System.out.println(list);
        return list;
    }

    //计算相似度
    private static double getUserSimilar(Map<String, Double> pm1, Map<String, Double> pm2) {
        int n = 0;// 数量n
        int sxy = 0;// Σxy=x1*y1+x2*y2+....xn*yn
        int sx = 0;// Σx=x1+x2+....xn
        int sy = 0;// Σy=y1+y2+...yn
        int sx2 = 0;// Σx2=(x1)2+(x2)2+....(xn)2
        int sy2 = 0;// Σy2=(y1)2+(y2)2+....(yn)2

        for (Map.Entry<String, Double> pme : pm1.entrySet()) {
            String key = pme.getKey();
            Double x = pme.getValue();
            Double y = pm2.get(key);
            if (x != null && y != null) {
                n++;
                sxy += x * y;
                sx += x;
                sy += y;
                sx2 += Math.pow(x, 2);
                sy2 += Math.pow(y, 2);
            }
        }
        // p=(Σxy-Σx*Σy/n)/Math.sqrt((Σx2-(Σx)2/n)(Σy2-(Σy)2/n));
        double sd = 1;
        try {
            sd = sxy - sx * sy / n;
        } catch (ArithmeticException a) {

        }


        double sm = Math.sqrt((sx2 - Math.pow(sx, 2) / n) * (sy2 - Math.pow(sy, 2) / n));
        return Math.abs(sm == 0 ? 1 : sd / sm);
    }
}
